/**
 * 
 */
package com.jrh.biz.user;


import java.util.List;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.jrh.common.condition.Precondition;
import com.jrh.common.encrypt.CreateMD5;
import com.jrh.common.exception.UserAlreadyExistsException;
import com.jrh.common.util.DateUtils;
import com.jrh.dal.UserDao;
import com.jrh.dal.UserProfileDao;
import com.jrh.domain.entity.User;
import com.jrh.domain.entity.UserProfile;

/**
 * 用户服务实现
 * 
 * @author mmy 2012-7-18 上午3:25:03
 */
public class UserServiceImpl implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    private UserDao             userDao;

    private UserProfileDao      userProfileDao;

    private TransactionTemplate transactionTemplate;

    /**
     * 根据用户id取得用户附加信息
     * 
     * @param userId
     * @return
     */
    public UserProfile getUserProfileByUserId(Long userId) {
        return userProfileDao.getUserProfileByUserId(userId);
    }

    @Override
    public User getUserByLoginIdAndSite(String loginId, String site) {
        Precondition.checkNotBlank(loginId, "loginId can not blank!");
        if (StringUtils.isEmpty(site)) {
            site = User.JRH_SELF_USER_SITE;
        }
        return userDao.getUserByLoginIdAndSite(loginId, site);
    }

    @Override
    public User getUserByNickname(String nickname) {
        Precondition.checkNotBlank(nickname, "nickname can not blank!");
        return userDao.getUserByNickname(nickname);
    }

    @Override
    public User checkLogin(String loginId, String password, String site) {
        Precondition.checkNotBlank(loginId, "loginId can not blank!");
        Precondition.checkNotBlank(password, "password can not blank!");
        Precondition.checkNotBlank(site, "site can not blank!");
        User user = this.getUserByLoginIdAndSite(loginId, site);
        if (user == null) return null;
        if (!CreateMD5.createMD5(password).equals(user.getPassword())) return null;

        // 更新最后一次登录时间
        this.updateLastLoginTime(user.getId());

        return user;
    }

    @Override
    public User loadUser(Long id, String loginId) {
        Precondition.checkNotNull(id, "id can not null!");
        Precondition.checkNotBlank(loginId, "loginId can not blank!");
        User user = userDao.load(id);
        if (user == null || !loginId.equals(user.getLoginId())) {
            log.error("loginId discordant. id = {}, loginId = {}", id, loginId);
            return null;
        }
        return user;
    }

    @Transactional
    @Override
    public boolean createUser(final User user, UserProfile userProfilea) throws UserAlreadyExistsException {

        Precondition.checkNotNull(user, "user can not null!");
        Precondition.checkNotBlank(user.getLoginId(), "loginId can not blank!");
        Precondition.checkNotBlank(user.getPassword(), "password can not blank!");
        // Precondition.checkNotBlank(userProfilea.getQuestion(), "question can not blank!");
        // Precondition.checkNotBlank(userProfilea.getAnswer(), "answer can not blank!");
        if (StringUtils.isBlank(user.getSite())) {
            user.setSite(User.JRH_SELF_USER_SITE);
        }
        if (StringUtils.isBlank(user.getUserType())) {
            user.setUserType(User.USER_TYPE_BUYER);
        }
        User lg_user = this.getUserByLoginIdAndSite(user.getLoginId(), user.getSite());
        if (lg_user != null) {
            log.debug("User already exists. user = {}", user);
            throw new UserAlreadyExistsException(UserAlreadyExistsException.ERROR_CODE_LOGINID,
                                                 "user loginId already exists.");
        }
        if (userProfilea == null) {
            userProfilea = new UserProfile();
        }
        final UserProfile userProfile = userProfilea;
        User ulike_user = userDao.getUserByNickname(user.getNickname());
        if (ulike_user != null) {
            log.debug("User already exists. user = {}", user);
            throw new UserAlreadyExistsException(UserAlreadyExistsException.ERROR_CODE_NICKNAME,
                                                 "user nickname already exists.");
        }
        user.setPassword(CreateMD5.createMD5(user.getPassword()));
        return (Boolean) transactionTemplate.execute(new TransactionCallback<Boolean>() {

            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                try {
                    userDao.create(user);
                    userProfile.setUserId(user.getId());
                    userProfileDao.create(userProfile);
                    return Boolean.TRUE;
                } catch (Exception e) {
                    log.error("createUser error. errorMsg = {}, user = {}, userProfile = {}",
                              new Object[] { e.getMessage(), user, userProfile });
                    status.setRollbackOnly();
                }
                return Boolean.FALSE;
            }
        });
    }

    public UserProfile getUserProfileByLoginId(String loginId) {
        Precondition.checkNotBlank(loginId, "loginId can not null!");
        User user = userDao.getUserByLoginId(loginId);
        if (user == null) return null;
        return userProfileDao.getUserProfileByUserId(user.getId());
    }

    @Override
    public boolean forgetpassword(String loginId, String password, String answer) {
        Precondition.checkNotBlank(loginId, "loginId can not null!");
        Precondition.checkNotBlank(password, "password can not null!");
        Precondition.checkNotBlank(answer, "answer can not blank!");
        User user = userDao.getUserByLoginId(loginId);
        if (user == null) return Boolean.FALSE;
        UserProfile userProfile = userProfileDao.getUserProfileByUserId(user.getId());
        if (!answer.equals(userProfile.getAnswer())) return Boolean.FALSE;
        user.setPassword(CreateMD5.createMD5(password));
        return userDao.update(user);
    }

    @Override
    public boolean updatePassword(User user, String newPassword) {
        Precondition.checkNotNull(user, "user can not null!");
        Precondition.checkNotNull(user.getId(), "id can not null!");
        Precondition.checkNotBlank(user.getLoginId(), "loginId can not blank!");
        User p_user = this.loadUser(user.getId(), user.getLoginId());
        if (p_user == null) return Boolean.FALSE;
        if (!CreateMD5.createMD5(user.getPassword()).equals(p_user.getPassword())) return Boolean.FALSE;

        user.setPassword(CreateMD5.createMD5(newPassword));

        boolean isSuccess = Boolean.FALSE;
        try {
            isSuccess = userDao.update(user);
            if (isSuccess) return Boolean.TRUE;
        } catch (Exception e) {
            log.error("updatePassword error. user = {}", user);
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean updateUser(User user) {
        Precondition.checkNotNull(user, "user can not null!");
        Precondition.checkNotNull(user.getId(), "id can not null!");
        Precondition.checkNotBlank(user.getLoginId(), "loginId can not blank!");
        User p_user = this.loadUser(user.getId(), user.getLoginId());
        if (p_user == null) return Boolean.FALSE;
        boolean isSuccess = Boolean.FALSE;
        try {
            isSuccess = userDao.update(user);
            if (isSuccess) return Boolean.TRUE;
        } catch (Exception e) {
            log.error("updateUser error. user = {}", user);
        }
        return Boolean.FALSE;
    }

    @Override
    public boolean updateLastLoginTime(Long userId) {
        Precondition.checkNotNull(userId, "userId can not null!");
        User user = new User();
        user.setId(userId);
        user.setLastLoginTime(DateUtils.formatDate2String(new Date(), DateUtils.DEFAULTDATEPATTERN));
        return userDao.update(user);
    }
 
    @Override
	public boolean updateUserProfile(UserProfile userProfile) {
       Precondition.checkNotNull(userProfile, "userProfile can not null!");
       Precondition.checkNotNull(userProfile.getId(), "id can not null!");
       Precondition.checkNotNull(userProfile.getUserId(), "userId can not blank!");
       UserProfile p_userProfile = userProfileDao.load(userProfile.getId());
       if (p_userProfile == null) return Boolean.FALSE;
       if (!p_userProfile.getUserId().equals(userProfile.getUserId())) return Boolean.FALSE;
       boolean isSuccess = Boolean.FALSE;
       try {
           isSuccess = userProfileDao.update(userProfile);
           if (isSuccess) return Boolean.TRUE;
       } catch (Exception e) {
           log.error("updateUserProfile error. userProfile = {}", userProfile);
       }
       return Boolean.FALSE;
	}

    public boolean updateUserProfile(UserProfile userProfile, String faceUrl) {
        Precondition.checkNotNull(userProfile, "userProfile can not null!");
        Precondition.checkNotNull(userProfile.getId(), "id can not null!");
        Precondition.checkNotNull(userProfile.getUserId(), "userId can not blank!");
        UserProfile p_userProfile = userProfileDao.load(userProfile.getId());
        if (p_userProfile == null) return Boolean.FALSE;
        if (!p_userProfile.getUserId().equals(userProfile.getUserId())) return Boolean.FALSE;
        boolean isSuccess = Boolean.FALSE;
        try {
            isSuccess = userProfileDao.update(userProfile);
            if (StringUtils.isNotBlank(faceUrl)) {
                User user = new User();
                user.setId(userProfile.getUserId());
                user.setFaceUrl(faceUrl);
                userDao.update(user);
            }
            if (isSuccess) return Boolean.TRUE;
        } catch (Exception e) {
            log.error("updateUserProfile error. userProfile = {}", userProfile);
        }
        return Boolean.FALSE;
    }


    @Override
    public boolean deleteUser(Long id, String loginId) {
        Precondition.checkNotNull(id, "id can not null!");
        Precondition.checkNotBlank(loginId, "loginId can not blank!");
        User p_user = this.loadUser(id, loginId);
        if (p_user == null) return Boolean.FALSE;
        try {
            userDao.delete(id);
            return Boolean.TRUE;
        } catch (Exception e) {
            log.error("deleteUser error. id = {}, loginId = {}", id, loginId);
        }
        return Boolean.FALSE;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setUserProfileDao(UserProfileDao userProfileDao) {
        this.userProfileDao = userProfileDao;
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

	@Override
	public List<User> finduserid() {
		return userDao.finduserid();
	}

	

}
